package com.skyd.core.android.game;

import com.skyd.core.vector.Vector2DF;

/**
 * 步进向量变化，不支持循环和持续时间设置
 * 
 * @author SkyD
 * 
 */
public class GameVector2DFStepMotion extends GameMotion {

	/**
	 * 构造函数
	 * 
	 * @param stepLength
	 *            步进长度
	 * @param targetPosition
	 *            目标位置
	 */
	public GameVector2DFStepMotion(float stepLength, Vector2DF targetPosition,
			IGameReadonlyValueDuct<GameObject, Vector2DF> valueDuct) {
		super();

		setTargetPosition(targetPosition);
		setStepLength(stepLength);
		setValueDuct(valueDuct);
		
	}

	/**
	 * 初始值为null。 功能注释：值读取管道
	 */
	private IGameReadonlyValueDuct<GameObject, Vector2DF> _ValueDuct = null;

	/**
	 * 获取ValueDuct。 功能注释：值读取管道
	 * 
	 * @return 当前的IGameReadonlyValueDuct<GameObject, Vector2DF>类型的值
	 */
	public IGameReadonlyValueDuct<GameObject, Vector2DF> getValueDuct() {
		return _ValueDuct;
	}

	/**
	 * 设置ValueDuct。 功能注释：值读取管道
	 * 
	 * @param value
	 *            要设置的IGameReadonlyValueDuct<GameObject, Vector2DF>类型值
	 */
	public void setValueDuct(IGameReadonlyValueDuct<GameObject, Vector2DF> value) {
		_ValueDuct = value;
	}

	/**
	 * 设置ValueDuct为其默认值(null)。 功能注释：值读取管道
	 */
	public void setValueDuctToDefault() {
		setValueDuct(null);
	}

	/**
	 * 初始值为0.01f。 功能注释：容差
	 */
	private float _Tolerance = 0.01f;
	/**
	 * 初始值为null。 功能注释：移动的目标位置
	 */
	private Vector2DF _TargetPosition = null;

	@Override
	protected void restart(GameObject obj) {

	}

	/**
	 * 获取Tolerance。 功能注释：容差
	 * 
	 * @return 当前的float类型的值
	 */
	public float getTolerance() {
		return _Tolerance;
	}

	/**
	 * 设置Tolerance。 功能注释：容差
	 * 
	 * @param value
	 *            要设置的float类型值
	 */
	public void setTolerance(float value) {
		_Tolerance = value;
	}

	/**
	 * 设置Tolerance为其默认值(0.01f)。 功能注释：容差
	 */
	public void setToleranceToDefault() {
		setTolerance(0.01f);
	}

	@Override
	protected void updateSelf(GameObject obj) {

	}

	/**
	 * 初始值为0f。 功能注释：步进长度
	 */
	private float _StepLength = 0f;

	/**
	 * 获取StepLength。 功能注释：步进长度
	 * 
	 * @return 当前的float类型的值
	 */
	public float getStepLength() {
		return _StepLength;
	}

	/**
	 * 设置StepLength。 功能注释：步进长度
	 * 
	 * @param value
	 *            要设置的float类型值
	 */
	public void setStepLength(float value) {
		_StepLength = value;
	}

	/**
	 * 设置StepLength为其默认值(0f)。 功能注释：步进长度
	 */
	public void setStepLengthToDefault() {
		setStepLength(0f);
	}

	@Override
	protected boolean getIsComplete(GameObject obj) {
		return checkComplete(getValueDuct().getValueFrom(obj));
	}

	@Override
	protected void updateTarget(GameObject obj) {
		changePosition(getValueDuct().getValueFrom(obj));
	}

	/**
	 * 获取TargetPosition。 功能注释：移动的目标位置
	 * 
	 * @return 当前的Vector2DF类型的值
	 */
	public Vector2DF getTargetPosition() {
		return _TargetPosition;
	}

	/**
	 * 设置TargetPosition。 功能注释：移动的目标位置
	 * 
	 * @param value
	 *            要设置的Vector2DF类型值
	 */
	public void setTargetPosition(Vector2DF value) {
		_TargetPosition = value;
	}

	/**
	 * 设置TargetPosition为其默认值(null)。 功能注释：移动的目标位置
	 */
	public void setTargetPositionToDefault() {
		setTargetPosition(null);
	}

	/**
	 * 检验是否完成
	 * 
	 * @param nowPosition
	 *            当前位置
	 * @return 是否完成
	 */
	protected boolean checkComplete(Vector2DF nowPosition) {
		return nowPosition.minusNew(getTargetPosition()).getLength() <= getTolerance();
	}

	/**
	 * 改变当前位置
	 * 
	 * @param nowPosition
	 */
	protected void changePosition(Vector2DF nowPosition) {
		Vector2DF v = getRelativePosition(nowPosition);
		if (v.getLength() <= getStepLength()) {
			nowPosition.resetWith(getTargetPosition());
		} else {
			nowPosition.plus(getStepVector(v.getAngle()));
		}
	}
	
	/**
	 * 获取步进向量
	 * @param angle 步进方向
	 * @return 步进向量
	 */
	protected Vector2DF getStepVector(float angle){
		Vector2DF n = new Vector2DF(0, 0);
		n.setLength(getStepLength());
		n.setAngle(angle);
		return n;
	}

	/**
	 * 获取目标位置与当前位置的相对位置
	 * @param nowPosition 当前位置
	 * @return 相对位置
	 */
	protected Vector2DF getRelativePosition(Vector2DF nowPosition){
		return getTargetPosition().minusNew(nowPosition);
	}
}
